home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Basic / Visual Basic.60 / COMMON / TOOLS / VCM / VCM.MDB / VcmComponentContainer / 05_Cabinet / LHDRDLG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-18  |  16.6 KB  |  558 lines

  1. // ListHdrDlg.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "ListHdr.h"
  15. #include "LHdrDlg.h"
  16.  
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CAboutDlg dialog used for App About
  25.  
  26. class CAboutDlg : public CDialog
  27. {
  28. public:
  29.     CAboutDlg();
  30.  
  31. // Dialog Data
  32.     //{{AFX_DATA(CAboutDlg)
  33.     enum { IDD = IDD_ABOUTBOX };
  34.     //}}AFX_DATA
  35.  
  36.     // ClassWizard generated virtual function overrides
  37.     //{{AFX_VIRTUAL(CAboutDlg)
  38.     protected:
  39.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  40.     //}}AFX_VIRTUAL
  41.  
  42. // Implementation
  43. protected:
  44.     //{{AFX_MSG(CAboutDlg)
  45.     //}}AFX_MSG
  46.     DECLARE_MESSAGE_MAP()
  47. };
  48.  
  49. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  50. {
  51.     //{{AFX_DATA_INIT(CAboutDlg)
  52.     //}}AFX_DATA_INIT
  53. }
  54.  
  55. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  56. {
  57.     CDialog::DoDataExchange(pDX);
  58.     //{{AFX_DATA_MAP(CAboutDlg)
  59.     //}}AFX_DATA_MAP
  60. }
  61.  
  62. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  63.     //{{AFX_MSG_MAP(CAboutDlg)
  64.         // No message handlers
  65.     //}}AFX_MSG_MAP
  66. END_MESSAGE_MAP()
  67.  
  68. /////////////////////////////////////////////////////////////////////////////
  69. // CListHdrDlg dialog
  70.  
  71. CListHdrDlg::CListHdrDlg(CWnd* pParent /*=NULL*/)
  72.     : CDialog(CListHdrDlg::IDD, pParent)
  73. {
  74.     //{{AFX_DATA_INIT(CListHdrDlg)
  75.     m_bNoLabelWrap = FALSE;
  76.     m_bAutoArrange = FALSE;
  77.     m_bSingleSel = FALSE;
  78.     m_bEditLabels = FALSE;
  79.     m_bNoColHdr = FALSE;
  80.     m_bNoSortHdr = FALSE;
  81.     m_strViewMode = _T("REPORT");
  82.     m_strAlignMode = _T("ALIGNTOP");
  83.     m_strSortMode = _T("None");
  84.     m_bHoverSelect = FALSE;
  85.     m_bWorkAreas = FALSE;
  86.     //}}AFX_DATA_INIT
  87.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  88.  
  89.     m_bHotCursor= TRUE;
  90.     m_pImageHdrSmall = NULL;
  91.     m_pImageList = NULL;
  92.     m_pImageListSmall = NULL;
  93. }
  94.  
  95. CListHdrDlg::~CListHdrDlg()
  96. {
  97.     if( m_pImageHdrSmall != NULL)
  98.         delete m_pImageHdrSmall;
  99.     if( m_pImageList != NULL)
  100.         delete m_pImageList;
  101.     if( m_pImageListSmall != NULL)
  102.         delete m_pImageListSmall;
  103. }
  104.  
  105. void CListHdrDlg::DoDataExchange(CDataExchange* pDX)
  106. {
  107.     CDialog::DoDataExchange(pDX);
  108.     //{{AFX_DATA_MAP(CListHdrDlg)
  109.     DDX_Control(pDX, IDC_LISTVIEW1, m_listctrl);
  110.     DDX_Check(pDX, IDC_NOLABELWRAP, m_bNoLabelWrap);
  111.     DDX_Check(pDX, IDC_AUTOARRANGE, m_bAutoArrange);
  112.     DDX_Check(pDX, IDC_SINGLESEL, m_bSingleSel);
  113.     DDX_Check(pDX, IDC_EDITLABELS, m_bEditLabels);
  114.     DDX_Check(pDX, IDC_NOCOLUMNHEADER, m_bNoColHdr);
  115.     DDX_Check(pDX, IDC_NOSORTHEADER, m_bNoSortHdr);
  116.     DDX_CBString(pDX, IDC_VIEWMODE, m_strViewMode);
  117.     DDX_CBString(pDX, IDC_ALIGN, m_strAlignMode);
  118.     DDX_CBString(pDX, IDC_SORT, m_strSortMode);
  119.     DDX_Check(pDX, IDC_HOVER, m_bHoverSelect);
  120.     DDX_Check(pDX, IDC_WORKAREAS, m_bWorkAreas);
  121.     //}}AFX_DATA_MAP
  122. }
  123.  
  124. BEGIN_MESSAGE_MAP(CListHdrDlg, CDialog)
  125.     //{{AFX_MSG_MAP(CListHdrDlg)
  126.     ON_WM_PAINT()
  127.     ON_WM_QUERYDRAGICON()
  128.     ON_BN_CLICKED(IDC_NOLABELWRAP, OnNoLabelWrap)
  129.     ON_BN_CLICKED(IDC_AUTOARRANGE, OnAutoArrange)
  130.     ON_BN_CLICKED(IDC_EDITLABELS, OnEditLabels)
  131.     ON_BN_CLICKED(IDC_NOCOLUMNHEADER, OnNoColHdr)
  132.     ON_BN_CLICKED(IDC_NOSORTHEADER, OnNoSortHdr)
  133.     ON_BN_CLICKED(IDC_SINGLESEL, OnSingleSel)
  134.     ON_CBN_SELCHANGE(IDC_ALIGN, OnChangeAlign)
  135.     ON_CBN_SELCHANGE(IDC_VIEWMODE, OnChangeView)
  136.     ON_BN_CLICKED(IDC_HOVER, OnHover)
  137.     ON_BN_CLICKED(IDC_MYHOTCUR, OnMyHotCur)
  138.     ON_CBN_SELCHANGE(IDC_SORT, OnChangeSort)
  139.     ON_BN_CLICKED(IDC_WORKAREAS, OnWorkAreas)
  140.     ON_BN_CLICKED(IDC_STDHOTCUR, OnStdHotCur)
  141.     ON_BN_CLICKED(IDABOUT, OnAbout)
  142.     //}}AFX_MSG_MAP
  143. END_MESSAGE_MAP()
  144.  
  145. /////////////////////////////////////////////////////////////////////////////
  146. // CListHdrDlg message handlers
  147.  
  148. BOOL CListHdrDlg::OnInitDialog()
  149. {
  150.     CListHdrApp     *pApp;
  151.     CRect           rect;
  152.  
  153.     CDialog::OnInitDialog();  // let the base class do the default work
  154.     UpdateData(TRUE);  // bring the information from the dialog.
  155.     pApp = (CListHdrApp *)AfxGetApp();
  156.     srand((unsigned) time(NULL));  // start the random number generator
  157.  
  158.     // create image list for header items
  159.     m_pImageHdrSmall = new CImageList();
  160.     ASSERT(m_pImageHdrSmall != NULL);    // serious allocation failure checking
  161.     m_pImageHdrSmall->Create(16, 16, ILC_MASK, 2, 2);
  162.     m_pImageHdrSmall->Add(pApp->LoadIcon(IDI_HDRICON1));
  163.     m_pImageHdrSmall->Add(pApp->LoadIcon(IDI_HDRICON2));
  164.  
  165.     // fill in image lists
  166.     m_pImageList = new CImageList();
  167.     m_pImageListSmall = new CImageList();
  168.     ASSERT(m_pImageList != NULL && m_pImageListSmall != NULL);    // serious allocation failure checking
  169.     m_pImageList->Create(32, 32, TRUE,  4, 4);
  170.     m_pImageListSmall->Create(16, 16, TRUE, 4, 4);
  171.     m_pImageList->Add(pApp->LoadIcon(IDI_ICONLIST1));
  172.     m_pImageList->Add(pApp->LoadIcon(IDI_ICONLIST2));
  173.     m_pImageList->Add(pApp->LoadIcon(IDI_ICONLIST3));
  174.     m_pImageList->Add(pApp->LoadIcon(IDI_ICONLIST4));
  175.     m_pImageListSmall->Add(pApp->LoadIcon(IDI_ICONLIST1));
  176.     m_pImageListSmall->Add(pApp->LoadIcon(IDI_ICONLIST2));
  177.     m_pImageListSmall->Add(pApp->LoadIcon(IDI_ICONLIST3));
  178.     m_pImageListSmall->Add(pApp->LoadIcon(IDI_ICONLIST4));
  179.  
  180.     // initialize the standard and custom hot cursors
  181.     m_hMyHotCursor= pApp->LoadCursor(IDC_SPYGLASS);
  182.     m_hStdHotCursor= m_listctrl.GetHotCursor();
  183.  
  184.     FillListCtrl();
  185.  
  186.     // Enable/disable inter-dependent list control styles
  187.     ((CButton*)GetDlgItem(IDC_STDHOTCUR))->SetCheck(m_bHotCursor);
  188.     GetDlgItem(IDC_STDHOTCUR)->EnableWindow(m_bHoverSelect);
  189.     GetDlgItem(IDC_MYHOTCUR)->EnableWindow(m_bHoverSelect);
  190.     GetDlgItem(IDC_WORKAREAS)->EnableWindow(FALSE);
  191.     GetDlgItem(IDC_ALIGN)->EnableWindow(FALSE);  // default is  report mode Does not support this
  192.     GetDlgItem(IDC_AUTOARRANGE)->EnableWindow(FALSE);
  193.  
  194.     return FALSE;  // there is no change in any control focus stuff here.
  195. }
  196.  
  197. // If you add a minimize button to your dialog, you will need the code below
  198. //  to draw the icon.  For MFC applications using the document/view model,
  199. //  this is automatically done for you by the framework.
  200. void CListHdrDlg::OnPaint()
  201. {
  202.     if (IsIconic())
  203.     {
  204.         CPaintDC dc(this); // device context for painting
  205.  
  206.         SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  207.  
  208.         // Center icon in client rectangle
  209.         int cxIcon = GetSystemMetrics(SM_CXICON);
  210.         int cyIcon = GetSystemMetrics(SM_CYICON);
  211.         CRect rect;
  212.         GetClientRect(&rect);
  213.         int x = (rect.Width() - cxIcon + 1) / 2;
  214.         int y = (rect.Height() - cyIcon + 1) / 2;
  215.  
  216.         // Draw the icon
  217.         dc.DrawIcon(x, y, m_hIcon);
  218.     }
  219.     else
  220.     {
  221.         CDialog::OnPaint();
  222.     }
  223. }
  224.  
  225. HCURSOR CListHdrDlg::OnQueryDragIcon()
  226. {
  227.     return (HCURSOR) m_hIcon;
  228. }
  229.  
  230. void CListHdrDlg::FillListCtrl()
  231. {
  232.     CRect           rect;
  233.     int             iIcon, iItem, iSubItem, iActualItem;
  234.     LV_ITEM         lvitem;
  235.     CString         strItem1= _T("ITEM");
  236.     CString         strItem2= _T("SUB_ITEM");
  237.     CString         strIconDesc[4], strIconShortDesc[4];
  238.     LPTSTR          pStrTemp1, pStrTemp2;
  239.     CListHdrApp     *pApp;
  240.  
  241.     strIconDesc[0]= _T("Blue Ellipse, Yellow Triangle, Red Rectangle");
  242.     strIconDesc[1]= _T("Yellow Ellipse, Red Triangle, Blue Rectangle");
  243.     strIconDesc[2]= _T("Red Ellipse, Blue Triangle, Yellow Rectangle");
  244.     strIconDesc[3]= _T("Red Ellipse, Yellow Triangle, Blue Rectangle");
  245.     strIconShortDesc[0]= _T("BE, YT, RR (Title)");
  246.     strIconShortDesc[1]= _T("YE, RT, BR (Title)");
  247.     strIconShortDesc[2]= _T("RE, BT, YR (Title)");
  248.     strIconShortDesc[3]= _T("RE, YT, BR (Title)");
  249.  
  250.  
  251.     pApp = (CListHdrApp *)AfxGetApp();
  252.     m_listctrl.SetImageList(m_pImageList, LVSIL_NORMAL);
  253.     m_listctrl.SetImageList(m_pImageListSmall, LVSIL_SMALL);
  254.  
  255.     // insert two columns (REPORT mode) and modify the new header items
  256.     m_listctrl.GetWindowRect(&rect);
  257.     m_listctrl.InsertColumn(0, strItem1, LVCFMT_LEFT,
  258.         rect.Width() * 1/3, 0);
  259.     m_listctrl.InsertColumn(1, strItem2, LVCFMT_LEFT,
  260.         rect.Width() * 2/3, 1);
  261.     ModifyHeaderItems();
  262.  
  263.     for (iItem = 0; iItem < 20; iItem++)  // insert the items and subitems into the list view.
  264.         for (iSubItem = 0; iSubItem < 2; iSubItem++)
  265.         {
  266.             if (iSubItem == 0)
  267.                 iIcon = rand() % 4;  // choose the icon and legend for the entry
  268.  
  269.             lvitem.mask = LVIF_TEXT | (iSubItem == 0? LVIF_IMAGE : 0);
  270.             lvitem.iItem = (iSubItem == 0)? iItem : iActualItem;
  271.             lvitem.iSubItem = iSubItem;
  272.  
  273.             // calculate the main and sub-item strings for the current item
  274.             pStrTemp1= strIconShortDesc[iIcon].GetBuffer(strIconShortDesc[iIcon].GetLength());
  275.             pStrTemp2= strIconDesc[iIcon].GetBuffer(strIconDesc[iIcon].GetLength());
  276.             lvitem.pszText = iSubItem == 0? pStrTemp1 : pStrTemp2;
  277.  
  278.             lvitem.iImage = iIcon;
  279.             if (iSubItem == 0)
  280.                 iActualItem = m_listctrl.InsertItem(&lvitem); // insert new item
  281.             else
  282.                 m_listctrl.SetItem(&lvitem); // modify existing item (the sub-item text)
  283.         }
  284. }
  285.  
  286. void CListHdrDlg::ModifyHeaderItems()
  287. {
  288.     HD_ITEM curItem;
  289.  
  290.     // retrieve embedded header control
  291.     CHeaderCtrl* pHdrCtrl= NULL;
  292.     pHdrCtrl= m_listctrl.GetHeaderCtrl();
  293.  
  294.     pHdrCtrl->SetImageList(m_pImageHdrSmall);
  295.     // add bmaps to each header item
  296.     pHdrCtrl->GetItem(0, &curItem);
  297.     curItem.mask= HDI_IMAGE | HDI_FORMAT;
  298.     curItem.iImage= 0;
  299.     curItem.fmt= HDF_LEFT | HDF_IMAGE | HDF_STRING;
  300.     pHdrCtrl->SetItem(0, &curItem);
  301.  
  302.     pHdrCtrl->GetItem(1, &curItem);
  303.     curItem.mask= HDI_IMAGE | HDI_FORMAT;
  304.     curItem.iImage= 1;
  305.     curItem.fmt= HDF_LEFT | HDF_IMAGE | HDF_STRING;
  306.     pHdrCtrl->SetItem(1, &curItem);
  307. }
  308.  
  309. // this function is used when a requested style
  310. // LVS_NOLABELWRAP, LVS_NOCOLUMNHEADER, and LVS_NOSORTHEADER
  311. // forces the current control to be re-created with the new style.
  312. void CListHdrDlg::RenewListCtrl(DWORD dwStyle, BOOL bSetBits)
  313. {
  314.     DWORD   dwStyleOld, dwExtStyles;
  315.     CRect   rect;
  316.  
  317.     dwStyleOld = GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE);
  318.     if (bSetBits)
  319.         dwStyleOld |= dwStyle;   // turn on bits specified by caller.
  320.     else
  321.         dwStyleOld &= ~dwStyle;  // turn off bits specified by caller.
  322.  
  323.     m_listctrl.GetWindowRect(&rect);
  324.     ScreenToClient(&rect);
  325.     dwExtStyles= m_listctrl.GetExtendedStyle(); //save extended styles
  326.     m_listctrl.DestroyWindow();
  327.     m_listctrl.Create(dwStyleOld, rect, this, IDC_LISTVIEW1);
  328.     m_listctrl.ModifyStyleEx(0,WS_EX_CLIENTEDGE); // renew the 3D border of the control
  329.     m_listctrl.SetExtendedStyle(dwExtStyles);
  330.  
  331.     FillListCtrl(); // repopulate with a new item group
  332.  
  333.     // work areas are not carried over with the new control
  334.     m_listctrl.SetWorkAreas(0, NULL);
  335.     m_bWorkAreas= FALSE;
  336.     UpdateData(FALSE);  // update the dialog
  337.  
  338. }
  339.  
  340. // this function is used when a requested style
  341. // can be applied to the existing control, and demonstrated.
  342. void CListHdrDlg::ChangeListCtrlStyle(DWORD dwStyle, BOOL bSetBits)
  343. {
  344.     CRect   rect;
  345.  
  346.     m_listctrl.GetWindowRect(&rect);
  347.     ScreenToClient(&rect);
  348.     ASSERT(dwStyle != 0);  // watch out for LVS_foo DEFINITIONS which are 0.
  349.     if (bSetBits)
  350.         m_listctrl.ModifyStyle(0, dwStyle);
  351.     else
  352.         m_listctrl.ModifyStyle(dwStyle, 0);
  353.  
  354.     InvalidateRect(rect);
  355.     UpdateData(FALSE);  // send information back to the dialog
  356. }
  357.  
  358. void CListHdrDlg::OnAutoArrange()
  359. {
  360.     UpdateData(TRUE);  // get the information from the dialog
  361.     ChangeListCtrlStyle(LVS_AUTOARRANGE, m_bAutoArrange);
  362. }
  363.  
  364. void CListHdrDlg::OnEditLabels()
  365. {
  366.     UpdateData(TRUE);
  367.     ChangeListCtrlStyle(LVS_EDITLABELS, m_bEditLabels);
  368. }
  369.  
  370. void CListHdrDlg::OnNoColHdr()
  371. {
  372.     UpdateData(TRUE);
  373.     RenewListCtrl(LVS_NOCOLUMNHEADER, m_bNoColHdr);
  374. }
  375.  
  376. void CListHdrDlg::OnNoSortHdr()
  377. {
  378.     UpdateData(TRUE);
  379.     RenewListCtrl(LVS_NOSORTHEADER, m_bNoSortHdr);
  380. }
  381.  
  382. void CListHdrDlg::OnSingleSel()
  383. {
  384.     UpdateData(TRUE);
  385.     ChangeListCtrlStyle(LVS_SINGLESEL, m_bSingleSel);
  386. }
  387.  
  388. void CListHdrDlg::OnNoLabelWrap()
  389. {
  390.     UpdateData(TRUE);
  391.     RenewListCtrl(LVS_NOLABELWRAP, m_bNoLabelWrap);
  392. }
  393.  
  394. void CListHdrDlg::OnChangeView()
  395. {
  396.  
  397.     long        lStyle, lStyleOld;
  398.     BOOL        bReport, bIconic;
  399.  
  400.     // retrieve view mode selection
  401.     UpdateData(TRUE);
  402.     if (m_strViewMode == _T("ICON"))
  403.         lStyle = LVS_ICON;
  404.     else if (m_strViewMode == _T("SMALL ICON"))
  405.         lStyle = LVS_SMALLICON;
  406.     else if (m_strViewMode == _T("REPORT"))
  407.         lStyle = LVS_REPORT;
  408.     else
  409.     {
  410.         ASSERT(m_strViewMode == _T("LIST"));
  411.         lStyle = LVS_LIST;
  412.     }
  413.  
  414.     // update interdependent styles, depending on view mode choice
  415.     bReport = lStyle == LVS_REPORT;
  416.     bIconic = lStyle == LVS_ICON || lStyle == LVS_SMALLICON;
  417.     GetDlgItem(IDC_NOSORTHEADER)->EnableWindow(bReport);
  418.     GetDlgItem(IDC_NOCOLUMNHEADER)->EnableWindow(bReport);
  419.     GetDlgItem(IDC_WORKAREAS)->EnableWindow(bIconic);
  420.     GetDlgItem(IDC_ALIGN)->EnableWindow(bIconic);
  421.     GetDlgItem(IDC_AUTOARRANGE)->EnableWindow(bIconic);
  422.  
  423.     lStyleOld = GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE);
  424.     lStyleOld &= ~(LVS_TYPEMASK);  // turn off all the style (view mode) bits
  425.     lStyleOld |= lStyle;        // Set the new style for the control
  426.     SetWindowLong(m_listctrl.m_hWnd, GWL_STYLE, lStyleOld);
  427.  
  428.     //In order to change the alignment, the control must be re-created.
  429.     //However, changing the view mode of a list control does not force a re-creation.
  430.     //Therefore, if the list view is in iconic mode, the control must be re-created
  431.     //to carry over the current alignment mode.
  432.     if(bIconic) //need to keep alignment also
  433.         RenewListCtrl(0, 0);
  434. }
  435.  
  436. void CListHdrDlg::OnChangeAlign()
  437. {
  438.     // this function takes into consideration that LVS_ALIGNTOP is defined as zero.
  439.     UpdateData(TRUE);
  440.     ASSERT(m_strAlignMode == _T("ALIGNTOP") || m_strAlignMode == _T("ALIGNLEFT"));
  441.     RenewListCtrl(LVS_ALIGNLEFT, (m_strAlignMode == _T("ALIGNLEFT")));
  442. }
  443.  
  444. void CListHdrDlg::OnHover()
  445. {
  446.     UpdateData(TRUE);
  447.  
  448.     if(m_bHoverSelect) // "hover selection" is enabled
  449.     {
  450.     // LVS_EX_ONECLICKACTIVATE (or LVS_EX_TWOCLICKACTIVATE must also be
  451.     // set before  "hover selection" is enabled
  452.         m_listctrl.SetExtendedStyle(LVS_EX_TRACKSELECT |
  453.             LVS_EX_ONECLICKACTIVATE);
  454.         GetDlgItem(IDC_STDHOTCUR)->EnableWindow(m_bHoverSelect);
  455.         GetDlgItem(IDC_MYHOTCUR)->EnableWindow(m_bHoverSelect);
  456.     }
  457.     else // "hover selection" is disabled
  458.     {
  459.         m_listctrl.SetExtendedStyle(0);
  460.         GetDlgItem(IDC_STDHOTCUR)->EnableWindow(m_bHoverSelect);
  461.         GetDlgItem(IDC_MYHOTCUR)->EnableWindow(m_bHoverSelect);
  462.     }
  463. }
  464.  
  465. void CListHdrDlg::OnMyHotCur()
  466. {
  467.     m_listctrl.SetHotCursor(m_hMyHotCursor);
  468.     m_bHotCursor= FALSE;
  469. }
  470.  
  471. void CListHdrDlg::OnChangeSort()
  472. {
  473.     long    lStyle;
  474.  
  475.     UpdateData(TRUE);
  476.     lStyle = GetWindowLong(m_listctrl.m_hWnd, GWL_STYLE);
  477.     lStyle &= ~(LVS_SORTASCENDING | LVS_SORTDESCENDING);
  478.     SetWindowLong(m_listctrl.m_hWnd, GWL_STYLE, lStyle);  // set style without sorting
  479.     if (m_strSortMode == _T("None"))
  480.         RenewListCtrl(LVS_SORTASCENDING | LVS_SORTDESCENDING, FALSE);
  481.     else if (m_strSortMode == _T("ASCENDING"))
  482.         RenewListCtrl(LVS_SORTASCENDING, TRUE);
  483.     else
  484.     {
  485.         ASSERT(m_strSortMode == _T("DESCENDING"));
  486.         RenewListCtrl(LVS_SORTDESCENDING, TRUE);
  487.     }
  488. }
  489.  
  490. void CListHdrDlg::OnWorkAreas()
  491. {
  492.     UpdateData(TRUE);
  493.  
  494.     if(m_bWorkAreas)
  495.     {
  496.         CRect curRect;
  497.         CSize size;
  498.  
  499.         size= m_listctrl.ApproximateViewRect();
  500.         size.cx+= 100;
  501.         size.cy+= 100;
  502.  
  503. /*      Work area layout
  504.         _____________________
  505.         |          |         |
  506.         |          |         |
  507.         |   0      |    1    |
  508.         |          |         |
  509.         |--------------------|
  510.         |          |         |
  511.         |   2      |    3    |
  512.         |          |         |
  513.         |__________|_________|*/
  514.  
  515.         CRect rcWorkAreas[4];
  516.  
  517.         rcWorkAreas[0].SetRect(0, 0, (size.cx / 2) - 5, (size.cy / 2) - 5);
  518.         rcWorkAreas[1].SetRect((size.cx / 2) + 5, 0, size.cx, (size.cy / 2) - 5);
  519.         rcWorkAreas[2].SetRect(0, (size.cy / 2) + 5, (size.cx / 2) - 5, size.cy);
  520.         rcWorkAreas[3].SetRect((size.cx / 2) + 5, (size.cy / 2) + 5, size.cx, size.cy);
  521.  
  522.         //set work areas
  523.         m_listctrl.SetWorkAreas(4, rcWorkAreas);
  524.  
  525.         // set insertion points for each work area
  526.         CPoint  rgptWork[4];
  527.         for (int i = 0; i < 4; i++)
  528.         {
  529.             rgptWork[i].x = rcWorkAreas[i].left + 10;
  530.             rgptWork[i].y = rcWorkAreas[i].top + 10;
  531.         }
  532.         // now move all the items to the different quadrants
  533.         for (i = 0; i < 20; i++)
  534.             m_listctrl.SetItemPosition(i, rgptWork[i % 4]);
  535.     }
  536.     else    //delete all work areas and re-organize items
  537.     {
  538.         m_listctrl.SetWorkAreas(0, NULL);
  539.  
  540.         CPoint pt(0, 0);
  541.         for (int i = 0; i < 20; i++)
  542.             m_listctrl.SetItemPosition(i, pt);  // move all the items to the origin
  543.     }
  544.     m_listctrl.Arrange(LVA_DEFAULT); // force the control to re-arrange the shuffled items
  545. }
  546.  
  547. void CListHdrDlg::OnStdHotCur()
  548. {
  549.     m_listctrl.SetHotCursor(m_hStdHotCursor);
  550.     m_bHotCursor= TRUE;
  551. }
  552.  
  553. void CListHdrDlg::OnAbout()
  554. {
  555.         CAboutDlg dlgAbout;
  556.         dlgAbout.DoModal();
  557. }
  558.